"use client";

import React, { useState, useEffect, useRef } from "react";
import { PreviewLayout, PreviewNavigation, PreviewContent } from "~/components/preview";
import { useParams, useSearchParams, useRouter } from "next/navigation";
import { api } from "~/trpc/react";
import { Spin, Empty, message, Typography, Divider, Anchor, Checkbox, Progress } from "antd";
import { LoadingOutlined, BookOutlined, CheckCircleOutlined, ClockCircleOutlined } from "@ant-design/icons";

const { Title, Text } = Typography;

const PreviewPage = () => {
  const params = useParams();
  const searchParams = useSearchParams();
  const router = useRouter();
  const contentRef = useRef<HTMLDivElement>(null);
  const taskRefs = useRef<Map<string, HTMLDivElement>>(new Map());
  const stepRefs = useRef<Map<string, HTMLDivElement>>(new Map());
  const courseId = params.courseId as string;
  
  // 从 URL 参数中获取选中的任务和步骤 ID
  const taskIdFromUrl = searchParams.get("taskId");
  const stepIdFromUrl = searchParams.get("stepId");
  
  const [selectedTaskId, setSelectedTaskId] = useState<string | undefined>(taskIdFromUrl || undefined);
  const [selectedStepId, setSelectedStepId] = useState<string | undefined>(stepIdFromUrl || undefined);
  const [scrolling, setScrolling] = useState(false); // 用于防止滚动和导航选择之间的循环

  // 获取课程信息
  const { data: course, isLoading: isCourseLoading } = api.courses.getById.useQuery(
    { courseId },
    { enabled: !!courseId }
  );

  // 获取课程任务数据
  const { data: tasks, isLoading: isTasksLoading, refetch: refetchTasks } = api.courses.getTasks.useQuery(
    { courseId },
    { enabled: !!courseId }
  );

  // 获取所有步骤内容，用于滚动导航
  const { data: allSteps, isLoading: isAllStepsLoading, refetch: refetchAllSteps } = api.courses.getAllSteps.useQuery(
    { courseId },
    { enabled: !!courseId }
  );

  // 获取课程进度
  const { data: enrollment, isLoading: isEnrollmentLoading } = api.courses.getEnrollment.useQuery(
    { courseId },
    { 
      enabled: !!courseId,
      refetchOnWindowFocus: true,
      refetchInterval: 10000 // 每10秒刷新一次进度
    }
  );

  // 本地步骤状态，用于立即更新UI
  const [localStepStates, setLocalStepStates] = useState<Map<string, boolean>>(new Map());

  // 计算课程进度
  const courseProgress = React.useMemo(() => {
    // 如果有本地状态，使用本地状态计算
    if (tasks && tasks.length > 0) {
      let totalSteps = 0;
      let completedSteps = 0;
      
      tasks.forEach(task => {
        if (task.steps && task.steps.length > 0) {
          task.steps.forEach(step => {
            totalSteps++;
            // 优先使用本地状态，如果没有则使用服务器状态
            const isCompleted = localStepStates.get(step.id) ?? 
              (step.completions && step.completions.length > 0);
            if (isCompleted) {
              completedSteps++;
            }
          });
        }
      });
      
      return totalSteps > 0 ? Math.round((completedSteps / totalSteps) * 100) : 0;
    }
    
    // 如果没有任务数据，则使用服务器返回的进度
    if (!enrollment) return 0;
    return enrollment.progress;
  }, [tasks, localStepStates, enrollment]);

  // 初始化本地步骤状态
  useEffect(() => {
    if (tasks) {
      const newLocalStepStates = new Map<string, boolean>();
      tasks.forEach(task => {
        task.steps?.forEach(step => {
          const isCompleted = step.completions && step.completions.length > 0;
          newLocalStepStates.set(step.id, isCompleted);
        });
      });
      setLocalStepStates(newLocalStepStates);
    }
  }, [tasks]);

  // 更新步骤状态的mutation
  const updateStepStatusMutation = api.steps.updateStatus.useMutation({
    onSuccess: (_, variables) => {
      message.success("步骤状态已更新");
      
      // 更新本地状态
      const newLocalStepStates = new Map(localStepStates);
      newLocalStepStates.set(variables.stepId, variables.status === "COMPLETED");
      setLocalStepStates(newLocalStepStates);
      
      // 更新数据
      void refetchTasks();
      void refetchAllSteps();
    },
    onError: (error) => {
      message.error(`更新失败: ${error.message}`);
      
      // 恢复本地状态
      if (tasks) {
        const newLocalStepStates = new Map(localStepStates);
        tasks.forEach(task => {
          task.steps?.forEach(step => {
            const isCompleted = step.completions && step.completions.length > 0;
            newLocalStepStates.set(step.id, isCompleted);
          });
        });
        setLocalStepStates(newLocalStepStates);
      }
    }
  });

  // 处理步骤完成状态变更
  const handleStepStatusChange = (stepId: string, checked: boolean) => {
    // 创建一个本地状态映射，用于立即更新UI
    const newLocalStepStates = new Map(localStepStates);
    newLocalStepStates.set(stepId, checked);
    setLocalStepStates(newLocalStepStates);
    
    updateStepStatusMutation.mutate({
      stepId,
      status: checked ? "COMPLETED" : "NOT_STARTED"
    });
  };

  // 将任务数据转换为导航项
  const navigationItems = React.useMemo(() => {
    if (!tasks) return [];
    return tasks.map((task) => ({
      key: task.id,
      title: task.title,
      children: task.steps?.map((step) => {
        // 优先使用本地状态，如果没有则使用服务器状态
        const isCompleted = localStepStates.get(step.id) ?? 
          (step.completions && step.completions.length > 0);
        
        return {
          key: `${task.id}-${step.id}`,
          title: step.title,
          isCompleted: isCompleted
        };
      }),
    }));
  }, [tasks, localStepStates]);

  // 处理导航项选择
  const handleSelect = (key: string) => {
    if (scrolling) return; // 如果正在滚动，不处理导航选择
    
    if (key.includes("-")) {
      // 选择了步骤
      const [taskId, stepId] = key.split("-");
      setSelectedTaskId(taskId);
      setSelectedStepId(stepId);
      
      // 更新 URL
      router.push(`/courses/${courseId}/preview?taskId=${taskId}&stepId=${stepId}`);
      
      // 滚动到对应的步骤
      const stepElement = stepRefs.current.get(key);
      if (stepElement) {
        setScrolling(true);
        stepElement.scrollIntoView({ behavior: "smooth" });
        setTimeout(() => setScrolling(false), 800); // 滚动完成后重置状态
      }
    } else {
      // 选择了任务
      setSelectedTaskId(key);
      setSelectedStepId(undefined);
      
      // 更新 URL
      router.push(`/courses/${courseId}/preview?taskId=${key}`);
      
      // 滚动到对应的任务
      const taskElement = taskRefs.current.get(key);
      if (taskElement) {
        setScrolling(true);
        taskElement.scrollIntoView({ behavior: "smooth" });
        setTimeout(() => setScrolling(false), 800); // 滚动完成后重置状态
      }
    }
  };

  // 处理滚动事件，根据滚动位置更新导航选中状态
  const handleScroll = React.useCallback(() => {
    if (!contentRef.current || scrolling || !tasks) return;
    
    // 防止频繁触发
    setScrolling(true);
    
    // 获取当前可视区域
    const contentElement = contentRef.current;
    const scrollTop = contentElement.scrollTop;
    const viewportHeight = contentElement.clientHeight;
    const viewportCenter = scrollTop + viewportHeight / 2;
    
    // 找到当前可见的步骤
    let visibleKey: string | null = null;
    let minDistance = Infinity;
    
    // 检查所有步骤元素
    stepRefs.current.forEach((element, key) => {
      const rect = element.getBoundingClientRect();
      const elementTop = rect.top;
      const elementCenter = elementTop + rect.height / 2;
      
      // 计算元素中心点与视口中心的距离
      const distance = Math.abs(elementCenter - (window.innerHeight / 2));
      
      // 如果这个元素比之前找到的更靠近视口中心
      if (distance < minDistance) {
        minDistance = distance;
        visibleKey = key;
      }
    });
    
    // 如果没有找到步骤，检查任务元素
    if (!visibleKey) {
      taskRefs.current.forEach((element, key) => {
        const rect = element.getBoundingClientRect();
        const elementTop = rect.top;
        const elementCenter = elementTop + rect.height / 2;
        
        // 计算元素中心点与视口中心的距离
        const distance = Math.abs(elementCenter - (window.innerHeight / 2));
        
        // 如果这个元素比之前找到的更靠近视口中心
        if (distance < minDistance) {
          minDistance = distance;
          visibleKey = key;
        }
      });
    }
    
    // 如果找到了可见的元素，更新选中状态
    if (visibleKey) {
      if (visibleKey.includes('-')) {
        // 是步骤
        const [taskId, stepId] = visibleKey.split('-');
        
        if (taskId !== selectedTaskId || stepId !== selectedStepId) {
          setSelectedTaskId(taskId);
          setSelectedStepId(stepId);
          
          // 更新 URL，但不触发页面跳转
          window.history.replaceState(
            {}, 
            "", 
            `/courses/${courseId}/preview?taskId=${taskId}&stepId=${stepId}`
          );
        }
      } else {
        // 是任务
        if (visibleKey !== selectedTaskId || selectedStepId !== undefined) {
          setSelectedTaskId(visibleKey);
          setSelectedStepId(undefined);
          
          // 更新 URL，但不触发页面跳转
          window.history.replaceState(
            {}, 
            "", 
            `/courses/${courseId}/preview?taskId=${visibleKey}`
          );
        }
      }
    }
    
    // 重置滚动状态
    setTimeout(() => setScrolling(false), 200);
  }, [courseId, scrolling, selectedStepId, selectedTaskId, tasks]);

  // 添加滚动监听
  useEffect(() => {
    const contentElement = contentRef.current;
    if (!contentElement) return;
    
    const throttledScrollHandler = () => {
      if (!scrolling) {
        requestAnimationFrame(handleScroll);
      }
    };
    
    contentElement.addEventListener("scroll", throttledScrollHandler);
    
    return () => {
      contentElement.removeEventListener("scroll", throttledScrollHandler);
    };
  }, [handleScroll, scrolling]);

  // 设置任务引用
  const setTaskRef = (key: string, element: HTMLDivElement | null) => {
    if (element) {
      taskRefs.current.set(key, element);
    } else {
      taskRefs.current.delete(key);
    }
  };

  // 设置步骤引用
  const setStepRef = (key: string, element: HTMLDivElement | null) => {
    if (element) {
      stepRefs.current.set(key, element);
    } else {
      stepRefs.current.delete(key);
    }
  };

  // 生成目录项
  const generateTocItems = React.useMemo(() => {
    if (!tasks) return [];
    
    return tasks.map(task => ({
      key: task.id,
      title: task.title,
      href: `#task-${task.id}`,
      children: task.steps?.map(step => ({
        key: `${task.id}-${step.id}`,
        title: step.title,
        href: `#step-${task.id}-${step.id}`,
      }))
    }));
  }, [tasks]);

  const isLoading = isCourseLoading || isTasksLoading || isAllStepsLoading;

  return (
    <div className="h-screen">
      <PreviewLayout
        title={course?.title}
        navigation={
          <PreviewNavigation
            items={navigationItems}
            onSelect={handleSelect}
            selectedKey={selectedStepId ? `${selectedTaskId}-${selectedStepId}` : selectedTaskId}
            isLoading={isTasksLoading}
          />
        }
        content={
          isLoading ? (
            <div className="flex items-center justify-center h-full">
              <Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} />
            </div>
          ) : !tasks || tasks.length === 0 ? (
            <div className="flex items-center justify-center h-full">
              <Empty description="此课程暂无内容" />
            </div>
          ) : (
            <div ref={contentRef} className="h-full overflow-auto pb-20">
              {/* 课程标题 */}
              <div className="mb-8">
                <Title level={1}>{course?.title}</Title>
                <Text type="secondary" className="text-lg">
                  {course?.description}
                </Text>
                
                {/* 课程进度 */}
                {!isEnrollmentLoading && enrollment && (
                  <div className="mt-4 p-4 bg-gray-50 rounded-lg">
                    <div className="flex items-center justify-between mb-2">
                      <Title level={5} className="m-0">课程进度</Title>
                      <Text strong>{courseProgress}%</Text>
                    </div>
                    <Progress 
                      percent={courseProgress} 
                      status={courseProgress === 100 ? "success" : "active"}
                      strokeColor={{
                        '0%': '#108ee9',
                        '100%': '#87d068',
                      }}
                    />
                    <div className="mt-2 text-right">
                      <Text type="secondary">
                        {courseProgress === 100 
                          ? "恭喜你完成了所有学习内容！" 
                          : "继续加油，完成剩余的学习内容！"}
                      </Text>
                    </div>
                  </div>
                )}
              </div>

              {/* 目录 */}
              <div className="mb-10 p-4 bg-gray-50 rounded-lg">
                <Title level={3} className="mb-4">目录</Title>
                <Anchor
                  items={generateTocItems}
                  affix={false}
                  className="custom-anchor"
                />
              </div>

              <Divider />

              {/* 内容区域 - 展示所有任务和步骤 */}
              {tasks.map((task) => (
                <div 
                  key={task.id} 
                  id={`task-${task.id}`}
                  ref={(el) => setTaskRef(task.id, el)}
                  className="mb-12"
                >
                  {/* 任务标题和内容 */}
                  <Title 
                    level={2} 
                    className="mb-6 pt-4 pb-2 border-b"
                    id={`task-${task.id}`}
                  >
                    <BookOutlined className="mr-2 text-blue-500" />
                    {task.title}
                  </Title>
                  
                  {task.content && (
                    <div className="mb-8">
                      <PreviewContent
                        content={task.content}
                        type="markdown"
                        className="border-0 shadow-none p-0"
                      />
                    </div>
                  )}
                  
                  {/* 步骤内容 */}
                  {task.steps && task.steps.map((step, index) => {
                    const isCompleted = localStepStates.get(step.id) ?? (step.completions && step.completions.length > 0);
                    return (
                      <div 
                        key={step.id}
                        id={`step-${task.id}-${step.id}`}
                        ref={(el) => setStepRef(`${task.id}-${step.id}`, el)}
                        className={`mb-8 pl-4 ${
                          selectedStepId === step.id ? 'bg-blue-50 p-4 rounded-lg border-l-4 border-blue-500' : ''
                        }`}
                      >
                        <div className="flex items-center mb-4">
                          <Title 
                            level={3} 
                            className="mb-0 mr-3"
                            id={`step-${task.id}-${step.id}`}
                          >
                            {index + 1}. {step.title}
                          </Title>
                          <Checkbox 
                            checked={isCompleted}
                            onChange={(e) => handleStepStatusChange(step.id, e.target.checked)}
                            className="ml-auto"
                          >
                            {isCompleted ? (
                              <span className="text-green-500 flex items-center">
                                <CheckCircleOutlined className="mr-1" /> 已完成
                              </span>
                            ) : (
                              <span className="text-orange-500 flex items-center">
                                <ClockCircleOutlined className="mr-1" /> 确认完成
                              </span>
                            )}
                          </Checkbox>
                        </div>
                        
                        {step.description && (
                          <PreviewContent
                            content={step.description}
                            type="markdown"
                            className="border-0 shadow-none p-0"
                          />
                        )}
                      </div>
                    );
                  })}
                </div>
              ))}
            </div>
          )
        }
      />
    </div>
  );
};

export default PreviewPage;
